from __future__ import annotations

from typing import Optional

import cv2
from numpy import ndarray
from roi import Roi


class Roimage(Roi):
    def __init__(
        self,
        width: float,
        height: float,
        x: float = 0,
        y: float = 0,
        parent: Optional[Roimage] = None,
        zoom: float = 1,
    ) -> None:
        Roi.__init__(self, width, height, x, y, parent, zoom)
        self.__image: Optional[ndarray] = None
        self.zoom_image_cache = {}

    @property
    def image(self):
        """
        获取当前 Roi 的图片，如果没有则从父 Roi 裁剪

        或设置当前 Roi 的图片
        """
        if self.__image is not None:
            return self.__image

        if self.zoom == 1:
            img = self.parent.image
        else:
            parent_img: ndarray = self.parent.image
            cache = self.parent.zoom_image_cache
            # 缓存过期
            if (parent_img != cache.get(self.parent.size)).any():
                cache.clear()
                cache[self.parent.size] = parent_img.copy()
            # 命中缓存
            size = (
                int(self.parent.width * self.zoom),
                int(self.parent.height * self.zoom),
            )
            img = cache.get(size)
            # 没命中
            if img is None:
                img = cache.setdefault(
                    size, cv2.resize(parent_img, size, interpolation=cv2.INTER_AREA)
                )
        return img[
            int(self.y) : int(self.y + self.height),
            int(self.x) : int(self.x + self.width),
        ]

    @image.setter
    def image(self, value):
        self.__image = value
